package manongfanshen.aba;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author ChangLiang
 * @date 2020/4/24
 */
public class AppTest {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private NoBlockingStack<String> stack = new NoBlockingStack<>();

    public Object LOCK = new Object();

    @BeforeEach
    public void setUp() {
        stack.push("C");
        stack.push("B");
        stack.push("A");
    }

    @Test
    @DisplayName("test aba")
    public void test() throws InterruptedException {

        // thread1 popA and cpu switch
        Thread threadA = new Thread("thread-1") {
            @Override
            public void run() {
                synchronized (LOCK) {
                    try {
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    logger.info(stack.pop());
                }
            }
        };
        threadA.start();
        Thread.sleep(20);

        // thread2 popA then popB then pushA
        Thread threadB = new Thread("thread-2") {
            @Override
            public void run() {
                synchronized (LOCK) {
                    logger.info(stack.pop());
                    logger.info(stack.pop());
                    stack.push("A");
                    LOCK.notify();
                }
            }
        };
        threadB.start();
        Thread.sleep(20);

        // occupy cpu and pop A then next point to B, this is error!
        threadA.join();
        threadB.join();
        logger.info(stack.head.get().item);
    }
}
